package com.lzw.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.lzw.entity.User;
import com.lzw.service.BaseService;
import com.lzw.service.UserService;
import com.lzw.utils.R;
import com.lzw.utils.ThreadLocalUtil;
import com.lzw.utils.TokenCryptoUtil;
import com.lzw.utils.TokenValidateTimeProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Objects;


@Service
@RequiredArgsConstructor
@Slf4j
public class BaseServiceImpl implements BaseService {

    private final UserService userService;
    private final TokenValidateTimeProperties tokenValidateTimeProperties;

    /**
     * 登录
     * @param user 登录的用户信息
     * @return
     */
    @Override
    public R login(User user) {
        //判断账号密码是否为空--前期不做验证
        //1，空值返回
        if(checkUserIsNull(user) == 0)
           return R.fail("账号或密码不能为空");
        //2，不空判断账号是否存在-密码是否正确
        User u = userService.selectByUsername(user.getUsername());
        if(BeanUtil.isEmpty(u))
            return R.fail("账号不存在");
        if(!Objects.equals(user.getPassword(), u.getPassword()))
            return R.fail("密码错误");
        //3,账号存在且密码正确--登录成功
        //补充--登陆成功后--返回token信息，用于校验认证
        String token = TokenCryptoUtil.getToken(u.getId().toString(), tokenValidateTimeProperties.getExpireTime());//这里,默认1天内生效
        String encryptToken = null;
        try {
            encryptToken = TokenCryptoUtil.encryptToken(token);
        } catch (Exception e) {
            log.error("token加密出错");
            return R.fail("登录失败");
        }
        return R.ok("登录成功",encryptToken);
    }

    /**
     *  注册
     * @param user 注册的用户信息
     * @return
     */
    @Override
    public R register(User user) {
        //1,空值返回
        if(checkUserIsNull(user) == 0)
            return R.fail("账号或密码不能为空");
        //2,判断账号是否存在
        if(checkUserIsExistByUsername(user.getUsername()) != 0)
            return R.fail("账号已存在");
        //3,账号不存在,添加用户--注册成功
        if(userService.save(user) == 0)
            return R.fail("注册失败");
        return R.ok("注册成功");
    }

    /**
     * 登出
     * @return
     */
    @Override
    public R logout() {
        //这里可以有两种操作--
        // 1,前端主动置空token,使其后续访问不在携带之前的token
        // 2,后端将无用的token,加入黑名单,在黑名单内的token访问无效--无论是否合法是否过期
        // 我们仍需要在后端使用方案二,因为前端只能防君子而无法防小人
        // 我们后端要做的就是防小人

        //获取线程中的 token并添加入黑名单
        TokenCryptoUtil.addTokenToBlacklist(ThreadLocalUtil.get("token"));
        return R.ok("登出成功");
    }

    /**
     * 判断用户是否为空
     * @param user 判断的目标用户
     * @return 0-空 1-不空
     */
    private int checkUserIsNull(User user) {
        if (BeanUtil.isEmpty(user) || StrUtil.isEmpty(user.getUsername()) || StrUtil.isEmpty(user.getPassword()))
            return 0;//0--表示账号密码为空
        return 1;//1--表示账号密码不为空
    }

    /**
     * 判断用户是否存在
     * @param username 判断的目标账号
     * @return 0-不存在 1-存在
     */
    private int checkUserIsExistByUsername(String username) {
        User u = userService.selectByUsername(username);
        if(BeanUtil.isEmpty(u))
            return 0;//0--表示账号不存在
        return 1;//1--表示账号存在
    }



}
